<?php

class Workset_File_Transfer_Adapter_Http extends Zend_File_Transfer_Adapter_Http {

    protected $_useOriginalFileName = false;

    protected $_generateRandomDestinationPath = true;

    protected $_generationOptions = array(
        'depth'     => 2,
        'perms'         => 0777
    );

    protected $_validated = false;

	function addFiles(array $files, $validator = null, $filter = null) {
		foreach ($files as $key => $fileinfo) {
			$fileinfo = array_merge($fileinfo, array(
					'options'   => $this->_options,
                    'validated' => false,
                    'received'  => false,
                    'filtered'  => false,	
			));
			$this->_files[$key] = $fileinfo;
		}
	}

    function useOriginalFileName($flag = true) {
        $this->_useOriginalFileName = (bool)$flag;
		return $this;
    }

    function setDestination($destination, $files = null) {
        if (is_array($destination)) {
            if (count($destination) < 1) {
                throw new Zend_File_Transfer_Exception('Empty destination path');
            }

            //fix if first element contains real path like "/home/path/"
            $sep = '';
            if (preg_match('|^[/\\\]|', $destination[0])) {
                $sep = DIRECTORY_SEPARATOR;
            } 

            $destination = array_map('trim', $destination, array_fill(0, count($destination), "/\\"));
            $destination = array_filter($destination);
            $destination = $sep.implode(DIRECTORY_SEPARATOR, $destination);
        } else {
            $destination = rtrim($destination, "/\\");
        }

        if ($this->_generateRandomDestinationPath) {
            $destination = $destination.DIRECTORY_SEPARATOR.$this->_generateDestinationPath();
            if (!$this->_createDestinationDir($destination)) {
                throw new Zend_File_Transfer_Exception('Can\'t create destination directory');
            }
        }

        parent::setDestination($destination, $files);
    }

	function isValid($files = null, $ignoreNotExists = true) {

		if ($this->_validated) {
			return true;
		}

		$found = array();

		if (empty($this->_files)) {
			return $ignoreNotExists;
		}

		if (null !== $files) {
			$files = (array)$files;
			$check = array_intersect_key($this->_files, array_flip($files));
		} else {
			$check = $this->_files;
		}

		foreach ($check as $key => $file) {

			//валидация массива файлов
			if (isset($file['multifiles']) && empty($file['validated'])) {

				foreach ((array)$file['multifiles'] as $name) {
					if (!isset($this->_files[$name])) {

						if (!$ignoreNotExists) {
							return false;
						}

						continue;
					}

					$f = $this->_files[$name];

					//опции
					if (isset($file['options'])) {

						if ($f['error'] == UPLOAD_ERR_NO_FILE && !empty($file['options']['ignoreNoFile'])) {
							continue;
						}

						if (!isset($this->_files[$name]['options'])) {
							$this->_files[$name]['options'] = array();
						}

						$this->_files[$name]['options'] = array_merge($this->_files[$name]['options'], $file['options']);
					}

					//валидация
					if (isset($file['validators'])) {

						//файл был провалидирован
						if (empty($f['validated'])) {

							if (!isset($f['validators'])) {
								$f['validators'] = array();
							}

							$this->_files[$name]['validators'] = array_unique( array_merge($f['validators'], $file['validators']) );

						} else {
							continue;
						}
					}

					$found[] = $name;
				}

				$this->_files[$key]['validated'] = true;

			}

			elseif (!empty($file['validators']) && empty($file['validated'])) {
				$found[] = $key;
			}
		}

		if (empty($found)) {
			return true;
		}

		//dump(array_intersect_key($this->_files, array_flip($found))); exit;

		return parent::isValid($found);

	}

    protected function _prepareFiles() {
        parent::_prepareFiles();

        if (!$this->_useOriginalFileName) {
            foreach ($this->_files as $name => $content) {
                $this->_files[$name]['name'] = $this->_generateFileName($this->_files[$name]['name']);
            }
        }
    }

    protected function _generateFileName($name) {
        $ext = substr($name, strrpos($name, '.') + 1);
        if ($ext) {
            $ext = strtolower($ext);
        }
        return md5(uniqid(null, true)).($ext ? '.'.$ext : '');
    }

    protected function _generateDestinationPath() {
        $opt = &$this->_generationOptions;
        $path = array();

        for ($i = 0; $i < $opt['depth']; $i++) {
            //$c = chr(mt_rand(97, 122));
            $c = dechex(mt_rand(1, 255));
            $c = str_pad($c, 2, '0', STR_PAD_LEFT);

            $path[] = $c;
        }

        $path = array_reverse($path);
        $path = implode(DIRECTORY_SEPARATOR, $path);

		return $path;
    }

    protected function _createDestinationDir($destination) {
        if (!is_dir($destination)) {
            $opt = &$this->_generationOptions;
            return mkdir($destination, $opt['perms'], true);
        } else {
            return true;
        }
    }

}

?>